<template>
  <div>

    <!-- 事件定义列表 -->
    <el-table max-height="450" :data="events">

      <el-table-column label="事件标识" align="center" prop="id"/>

      <el-table-column label="事件名称" align="center" prop="name"/>

      <el-table-column
        label="数据类型"
        align="center"
        prop="valueType.type"
        :filters="utils.getTableFiltersData(dict.type.iot_data_type)"
        :filter-method="utils.filterValueType"
      />

      <el-table-column
        label="事件等级"
        align="center"
        prop="type"
        :filters="utils.getTableFiltersData(dict.type.iot_events_level)"
        :filter-method="filterEventsType"
      >
        <template slot-scope="scope">
          <dict-tag :options="dict.type.iot_events_level" :value="scope.row.expands.level"/>
        </template>
      </el-table-column>

      <el-table-column label="描述" align="center" prop="description"/>

      <el-table-column label="事件数据" show-overflow-tooltip align="center" prop="eventData">
        <template slot-scope="scope">
          <el-link @click="viewEventData(scope.row)" type="primary">{{ scope.row.eventData }}</el-link>
        </template>
      </el-table-column>

      <el-table-column label="触发时间" align="center" prop="timeString"/>

      <el-table-column label="操作" align="center" min-width="100px" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-time"
            @click="viewHistoryRecord(scope.row)"
            v-hasPermi="['iot:device:list']"
          >历史
          </el-button>

          <el-button
            class="button-spacing"
            size="mini"
            type="text"
            icon="el-icon-help"
            @click="handleProtocolStandby(scope.row)"
            v-hasPermi="['iot:device:edit']"
          >协议
          </el-button>

          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['iot:device:edit']"
          >编辑
          </el-button>

          <el-popconfirm
            title="确认删除？"
            @confirm="handleDelete(scope.row)"
          >
            <el-button
              style="margin-left: 10px"
              size="mini"
              type="text"
              icon="el-icon-delete"
              v-hasPermi="['iot:device:remove']"
              slot="reference"
            >删除
            </el-button>
          </el-popconfirm>

        </template>
      </el-table-column>

    </el-table>

    <!-- 事件数据数据查看 -->
    <value-details ref="valueDetails"/>
    <!--历史事件数据查看-->
    <events-history ref="eventsHistory"/>
  </div>

</template>

<script>

import { mapState } from 'vuex'
import utils from '@/utils/iot/metadata'
import ValueDetails from '@/views/iot/device/physical-model/valueDetails'
import EventsHistory from '@/views/iot/device/physical-model/eventsHistory'
import { queryDeviceEvents } from '@/api/iot/device'
import { parseTime } from '@/utils/ruoyi'
import { formatDate } from '@/utils/dateUtils'
import { DataType } from '@/utils/iot/metadata/types/DataType'

export default {
  name: 'EventsTable',
  components: {
    ValueDetails,
    EventsHistory
  },
  // 字典
  dicts: [
    // 数据类型
    'iot_data_type',
    // 事件等级
    'iot_events_level'
  ],
  data() {
    return {
      //事件列表
      events: [],
      //引用
      utils,
      // 最新事件数据
      latestEventsData: new Map(),
      // 消息订阅id
      subIds: new Set()
    }
  },
  computed: {
    ...mapState({
      // 设备详情信息
      deviceDetailInfo: state => state.device.deviceDetailInfo,
      // 设备id
      deviceId: state => state.device.deviceId,
    })
  },

  watch: {
    deviceDetailInfo(data) {
      let metadata = JSON.parse(data.metadata)
      this.events = metadata.events
      this.setEventsData()

    },
    'events.length'() {
      // 事件数据订阅
      this.handleSubscribe()
      // 获取全部最新设备事件
      this.getAllEventsData()
    }
  },

  created() {
    let metadata = JSON.parse(this.deviceDetailInfo.metadata)
    this.events = metadata.events
    this.setEventsData()
  },

  destroyed() {
    // 取消订阅
    this.handleUnsubscribe()
  },

  methods: {

    /** 事件类型筛选 */
    filterEventsType(value, row) {
      return row.expands.level === value
    },

    /** 更新按钮操作 */
    handleUpdate(row) {
      this.$store.dispatch('EditDeviceEvents', row.id)
    },

    /** 删除按钮操作 */
    handleDelete(row) {
      // 删除事件
      this.$store.dispatch('DeleteDeviceMetadata', { type: 'events', id: row.id })
      // 删除协议支持
      this.$store.dispatch('DeleteDeviceProtocolStandby', row.id)
    },

    /** 协议支持按钮操作 */
    handleProtocolStandby(row) {
      this.$store.dispatch('ViewDeviceProtocolStandby',{ id: row.id, thingType: 'events' } )
    },

    /** 事件数据订阅*/
    handleSubscribe() {

      const data = this.events

      if (data.length <= 0) {
        return
      }

      const productId = this.deviceDetailInfo.productId
      const deviceId = this.deviceId
      let ids = []
      data.forEach(datum => ids.push(datum.id))

      if (ids.length <= 0) {
        return
      }

      let id = `instance-info-event-${productId}-${deviceId}`

      this.subIds.add(id)

      // 事件订阅
      this.socket.send({
        method: 'event',
        params: {
          subEvent: 'sub',
          content: {
            type: 'sub',
            id,
            topic: `/device/${productId}/${deviceId}/message/event/*`,
          }
        }
      }).then(async data => {

        const payload = data.payload
        const value = payload.data
        const event = payload.event

        let index = this.events.findIndex(item => item.id === event)

        if (index === -1) {
          return
        }

        let itemData = this.events[index]
        itemData.timeString = formatDate(payload.timestamp)
        itemData.timestamp = payload.timestamp
        itemData.originalValue = payload
        await DataType.format(itemData.valueType, value).then(formatValue => itemData.eventData = JSON.stringify(formatValue))
        this.latestEventsData.set(event, payload)

        this.$set(this.events, index, itemData)
      })
    },

    /** 取消订阅 */
    handleUnsubscribe() {
      this.subIds.forEach(id => {
        // 取消事件订阅
        this.socket.send({
          method: 'event',
          params: {
            subEvent: 'unsub',
            content: {
              type: 'unsub',
              id,
            }
          }
        })
      })
    },

    /** 获取全部最新设备事件 */
    getAllEventsData() {
      const deviceId = this.deviceId
      this.events.forEach(event => {
        queryDeviceEvents(deviceId, event.id, {
          pageIndex: 0,
          pageSize: 1
        }).then((response = {}) => {
          const list = response.data && response.data.data || []
          list.forEach(item => this.latestEventsData.set(event.id, item))
          this.setEventsData()
        })
      })
    },

    /** 设置事件数据*/
    setEventsData() {
      this.events.forEach((event, index) => {

        const latestData = this.latestEventsData.get(event.id)

        if (latestData) {
          event.originalValue = latestData.originalValue || latestData
          this.$set(event, 'eventData', JSON.stringify(latestData))
          const timestamp = latestData.timestamp
          if (timestamp) {
            this.$set(event, 'timeString', parseTime(timestamp))
          }
        }

      })
    },

    /** 查看事件数据 */
    viewEventData(data) {
      if (!data) {
        return
      }

      this.$refs.valueDetails.openDetails(data.originalValue, `详细信息（${data.id}）`)
    },

    /** 查看历史记录 */
    viewHistoryRecord(row) {
      this.$refs.eventsHistory.handleHistory(row.id)
    }
  }
}
</script>

<style scoped>
</style>
